//
//  PlSInjected.m
//  Injector
//
//  Created by ∞ on 26/11/07.
//  Copyright 2007 Emanuele Vulcano. All rights reserved.
//

#import "PlSInjected.h"
#import <CoreFoundation/CoreFoundation.h>
#import <dlfcn.h>
#import <assert.h>

#define kPlSInjectedBundleIdentifier CFSTR("net.infinite-labs.PlugSuit.PRIVATE.Injected")
#define kPlSSupportLibraryName CFSTR("PlugSuitSupport")
#define kPlSEntryPointName ("PlSInjectedStage2EntryPoint")

void PlSInjectedEntryPoint() {
	CFBundleRef bundle = CFBundleGetBundleWithIdentifier(kPlSInjectedBundleIdentifier);
	assert(bundle);
	
	CFURLRef stage2URL = CFBundleCopyResourceURL(bundle, kPlSSupportLibraryName, CFSTR("dylib"), NULL);
	assert(stage2URL);
	
	CFStringRef stage2Path = CFURLCopyFileSystemPath(stage2URL, kCFURLPOSIXPathStyle);
	assert(stage2Path);
	
	char fsrep[CFStringGetMaximumSizeOfFileSystemRepresentation(stage2Path)];
	CFStringGetFileSystemRepresentation(stage2Path, fsrep, sizeof(fsrep));
	
#ifdef PlSDebug
	fprintf(stderr, "from PlugSuit: [DEBUG] Got %s as file system representation of the dylib in pid %d.\n", fsrep, getpid());
#endif
	
	void* library = dlopen(fsrep, RTLD_NOW | RTLD_GLOBAL);
	if (!library)
		fprintf(stderr, "from PlugSuit: Could not load stage 2 because of a dlopen error. (%s in pid %d)\n", dlerror(), getpid());
	else {
		void (*handle)() = dlsym(library, kPlSEntryPointName);
		
		if (!handle)
			fprintf(stderr, "from PlugSuit: Could not find the stage 2 call symbol. (%s in pid %d)\n", dlerror(), getpid());
		else {
#ifdef PlSDebug
			fprintf(stderr, "from PlugSuit: [DEBUG] Found handle at %p.\n", handle);
#endif
			handle();
		}
		
		//dlclose(library); // do not risk losing the classes prematurely.
	}
	
	CFRelease(stage2Path);
	CFRelease(stage2URL);
}

